﻿/* 
 * Produzido por:
 *      Daniel Vargas
 *      Danilo Valvezon
 *      Fernanda Osaki
 *      Tiago Ricardo Almeida da Silva
 *      
 * FATEC São Caetano do Sul
 * Jogos NA6
 * */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace bomberboyonline
{
    // Classe que representa o fogo
    class Fogo : Microsoft.Xna.Framework.DrawableGameComponent
    {
        // Declaracao de variaveis
        private Texture2D textura;
        private int direcao, posicao, contadorVida;
        private Game game;
        private List<int> posicoesOcupadas, posicoesItens, posicoesFogo;

        // COnstrutor da classe
        public Fogo(Game game, int posicao, ref List<int> posicoesOcupadas, ref List<int> posicoesItens, ref List<int> posicoesFogo)
            : base(game)
        {
            // Atribuicao de valores das variaveis
            this.game = game;
            this.posicoesOcupadas = posicoesOcupadas;
            this.posicoesItens = posicoesItens;
            this.posicoesFogo = posicoesFogo;
            contadorVida = 20;            
            this.posicao = posicao;
            textura = game.Content.Load<Texture2D>("imagens\\fire");
            this.direcao = geraDirecao();
            // Metodo que verifica colisao com itens e os destroi caso seja verdadeiro
            verificaColisaoItens();
            // Metodo que veifica colisao com Blocos, e caso seja verdadeiro destroi bloco e caso tenha item embaixo seta como visivel
            verificaColisaoBlocos();            
        }

        // Metodo que calcula qual imagem que fogo tera
        private int geraDirecao()
        {
            int index = 0;
            //esq = 8  //dir = 2 //cima = 1 //baixo = 4               
            if (posicoesFogo.Contains(posicao - 1)) index += 8;
            if (posicoesFogo.Contains(posicao + 1)) index += 2;
            if (posicoesFogo.Contains(posicao - 17)) index += 1;
            if (posicoesFogo.Contains(posicao + 17)) index += 4;
            return index;
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {

            verificaVidaFogo(); // chama metodo que verifica vida do fogo
            verificaColisaoPersonagem(); // chama metodo que verifica colisao com personagem
            verificaColisaoBomba(); // chama metodo que verifica colisao com bombas
            this.direcao = geraDirecao(); // chama metodo que calcula imagem e atribui valor a variavel direcao
            base.Update(gameTime);
        }

        /// <summary>
        /// Allows the game component to draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Draw(GameTime gameTime)
        {
            // Pega o Spritebatch do Services
            SpriteBatch sBatch = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch));
            // Desenha o fundo
            sBatch.Draw(textura, Coordenadas.retangulos[posicao], new Rectangle(direcao*45,0,45,40), Color.White);

            base.Draw(gameTime);
        }

        // Metodo que verifica vida de fogo
        private void verificaVidaFogo()
        {
            if (contadorVida <= 0)// Se vida for = a 0
            {
                posicoesFogo.Remove(posicao); // Remove fogo da lista de posicoes de fogo
                game.Components.Remove(this); // removo fogo do jogo
            }
            else // Se vida for maio que 0
            {
                contadorVida--; // decrementa valor de vida
            }
        }

        // metodo que vrifica colisao com personagens
        private void verificaColisaoPersonagem()
        {
            IEnumerable<Personagem> ps = game.Components.OfType<Personagem>(); // pega lista de personagens
            foreach (Personagem player in ps) // faco um laco com cada personagem
            {
                if (player.getPosicao() == posicao) // Se posicao do fogo é igual a posicao do personagem
                {
                    player.morrer(); // personagem morre
                    //break; // acaba laco
                }
            }
        }

        // Metodo que verifica colisao com bombas
        private void verificaColisaoBomba()
        {
            if (posicoesOcupadas.Contains(posicao)) // Primeiramente verifico se fogo colide com algum objeto, se sim
            {
                IEnumerable<Bomba> bombas = game.Components.OfType<Bomba>(); // Pego lista de bombas
                foreach (Bomba bomba in bombas)
                {
                    if (bomba.getPosicao() == posicao) // para cada bomba vefico se a posicao do fogo é a mesma posicao da bomba
                    {
                        bomba.explode(ref posicoesOcupadas); // se sim explode bomba
                        break; // acaba laco
                    }
                }
            }
        }


        // Metodo que verifica colisao com itens e os destroi caso seja verdadeiro
        private void verificaColisaoItens()
        {
            if (posicoesItens.Contains(posicao)) // se houver algum item na mesma posicao que o fogo
            {
                IEnumerable<Item> itens = game.Components.OfType<Item>(); // pego os itens
                foreach (Item item in itens) 
                {
                    if (item.getPosicao() == posicao) // verifico cada item até achar o que tem a mesma posicao que o fogo
                    {
                        item.destruir(); // destroi item
                        break; //acaba laco
                    }
                }
            }
        }

        // Metodo que veifica colisao com Blocos, e caso seja verdadeiro destroi bloco e caso tenha item embaixo seta como visivel
        private void verificaColisaoBlocos()
        {
            if (posicoesOcupadas.Contains(posicao)) // se fogo tem posicao ocupada por outro objeto
            {
                IEnumerable<Bloco> blocos = game.Components.OfType<Bloco>(); // pego lista de blocos
                foreach (Bloco bloco in blocos)
                {
                    if (bloco.getPosicao() == posicao) // para cada bloco verifico sepossui mesma posicao que fogo
                    {
                        game.Components.Remove(bloco); // se sim, remove bloco do jogo
                        posicoesOcupadas.Remove(posicao); // remove posica de posicoesOcupadas
                        if (posicoesItens.Contains(posicao)) // se existe algum item na posicao do fogo
                        {
                            IEnumerable<Item> itens = game.Components.OfType<Item>(); // pego lista de itens
                            foreach(Item item in itens)
                            {
                                if(item.getPosicao() == posicao) // para cada item verifico se tem a posicao do fogo
                                {
                                    item.setVisivel(true); // mostro o item na tela do jogo
                                    break; // acaba laco de itens
                                }
                            }
                        }
                        break; // acaba laco de blocos
                    }
                }
            }            
        }

        // seta imagem do fogo
        public void setImagem(int direcao)
        {
            this.direcao = direcao;
        }
        
        // metodo get de posicao do fogo
        public int getPosicao()
        {
            return posicao;
        }
    }
}
